home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / manual-p / olxvman.tgz / olxvman.tar / olxvman / src / search.c < prev    next >
C/C++ Source or Header  |  1990-10-11  |  7KB  |  255 lines

  1. /*
  2.  * xman - X window system manual page display program.
  3.  *
  4.  * $XConsortium: search.c,v 1.11 89/10/03 15:58:01 kit Exp $
  5.  * $oHeader: search.c,v 4.0 88/08/31 22:13:19 kit Exp $
  6.  *
  7.  * Copyright 1987, 1988 Massachusetts Institute of Technology
  8.  *
  9.  * Permission to use, copy, modify, and distribute this software and its
  10.  * documentation for any purpose and without fee is hereby granted, provided
  11.  * that the above copyright notice appear in all copies and that both that
  12.  * copyright notice and this permission notice appear in supporting
  13.  * documentation, and that the name of M.I.T. not be used in advertising or
  14.  * publicity pertaining to distribution of the software without specific,
  15.  * written prior permission.  M.I.T. makes no representations about the
  16.  * suitability of this software for any purpose.  It is provided "as is"
  17.  * without express or implied warranty.
  18.  *
  19.  * Author:    Chris D. Peterson, MIT Project Athena
  20.  * Created:   November 3, 1987
  21.  */
  22.  
  23. #if ( !defined(lint) && !defined(SABER))
  24.   static char rcs_version[] = "$Athena: search.c,v 4.7 89/01/06 15:59:02 kit Exp $";
  25. #endif
  26.  
  27. #include <xview/xview.h>
  28. #include <xview/panel.h>
  29. #include <xview/textsw.h>
  30. #include <xview/xv_xrect.h>
  31. #include <xview/notice.h>
  32. #include <gdd.h>
  33. #include "olxvman_ui.h"
  34. #include "globals.h"
  35.  
  36. /* Map <CR> and control-M to goto begining of file. */
  37.  
  38. #define SEARCHARGS 10
  39.  
  40. FILE * DoManualSearch();
  41. static int BEntrySearch();
  42.  
  43. /*    Function Name: DoSearch
  44.  *    Description: This function performs a search for a man page or apropos
  45.  *                   search upon search string.
  46.  *    Arguments: man_globals - the pseudo globas for this manpage.
  47.  *                 type - the type of search.
  48.  *    Returns: none.
  49.  */
  50.  
  51. #define LOOKLINES 6
  52.  
  53. /* 
  54.  * Manual searches look through the list of manual pages for the right one
  55.  * with a binary search.
  56.  *
  57.  * Apropos searches still exec man -k.
  58.  *
  59.  * If nothing is found then I send a warning message to the user, and do
  60.  * nothing.
  61.  */
  62.  
  63. FILE *
  64. DoSearch(search_string, type)
  65. char *search_string;
  66. int type;
  67. {
  68.   char cmdbuf[BUFSIZ],*mantmp,*manpath;
  69.   char tmp[BUFSIZ],path[BUFSIZ];
  70.   char string_buf[BUFSIZ], cmp_str[BUFSIZ], error_buf[BUFSIZ];
  71.   FILE * file;
  72.   int count;
  73.   Bool flag;
  74.  
  75.   /* If the string is empty or starts with a space then do not search */
  76.  
  77.   if ( streq(search_string,"") ) {
  78.     PrintWarning("Search string is empty.");
  79.     return(NULL);
  80.   }
  81.  
  82.   if (search_string[0] == ' ') {
  83.     PrintWarning("First character cannot be a space.");
  84.     return(NULL);
  85.   }
  86.  
  87.   strcpy(tmp, MANTEMP);        /* get a temp file. */
  88.   mantmp = mktemp(tmp);
  89.  
  90.   /* set the command */
  91.  
  92.   manpath=getenv("MANPATH");
  93.   if (manpath == NULL || streq(manpath,"") )
  94.     strcpy(path,MANDIR);
  95.   else
  96.     strcpy(path,manpath);
  97.  
  98.   if (type == APROPOS) {
  99.     char label[BUFSIZ];
  100.  
  101.     sprintf(label,"Results of apropos search on: %s", search_string);
  102.  
  103. #ifdef NO_MANPATH_SUPPORT    /* not quite correct, but the best I can do. */
  104.     sprintf(cmdbuf, APROPOS_FORMAT, search_string, mantmp);
  105. #else
  106.     sprintf(cmdbuf, APROPOS_FORMAT, path, search_string, mantmp);
  107. #endif
  108.  
  109.     if(system(cmdbuf) != 0) {    /* execute search. */
  110.       sprintf(error_buf,"Something went wrong trying to run %s\n",cmdbuf);
  111.       PrintWarning(error_buf);
  112.     }
  113.  
  114.     if((file = fopen(mantmp,"r")) == NULL)
  115.       PrintError("lost temp file? out of temp space?");
  116.  
  117. /* 
  118.  * Since we keep the FD open we can unlink the file safely, this
  119.  * will keep extra files out of /tmp. 
  120.  */
  121.  
  122.     unlink(mantmp);
  123.  
  124.     sprintf(string_buf,"%s: nothing appropriate", search_string);
  125.  
  126.     /*
  127.      * Check first LOOKLINES lines for "nothing appropriate".
  128.      */
  129.   
  130.     count = 0;
  131.     flag = FALSE;
  132.     while ( (fgets(cmp_str, BUFSIZ, file) != NULL) && (count < LOOKLINES) ) {
  133.       if ( cmp_str[strlen(cmp_str) - 1] == '\n') /* strip off the '\n' */
  134.       cmp_str[strlen(cmp_str) - 1] = '\0';
  135.  
  136.       if (streq(cmp_str, string_buf)) {
  137.     flag = TRUE;
  138.     break;
  139.       }
  140.       count++;
  141.     }
  142.  
  143.     /*
  144.      * If the file is less than this number of lines then assume that there is
  145.      * nothing apropriate found. This does not confuse the apropos filter.
  146.      */
  147.  
  148.     if (flag) {
  149.       fclose(file);
  150.       file = NULL;
  151.       return(NULL);
  152.     }
  153.   
  154.     fseek(file, 0L, 0);        /* reset file to point at top. */
  155.   }
  156.   else {            /* MANUAL SEACH */
  157.     file = DoManualSearch(search_string);
  158.     if (file == NULL) {
  159.       sprintf(string_buf,"No manual entry for %s.", search_string);
  160.       return(NULL);
  161.     }
  162.   }
  163.  
  164.   return(file);
  165. }
  166.  
  167. /*    Function Name: DoManualSearch
  168.  *    Description: performs a manual search.
  169.  *    Arguments: man_globals - the manual page specific globals.
  170.  *    Returns: the filename of the man page.
  171.  */
  172.  
  173. #define NO_ENTRY -100
  174.  
  175. FILE * 
  176.   DoManualSearch(string)
  177. char * string;
  178. {
  179.     int e_num = NO_ENTRY;
  180.     int i;
  181.     
  182.     /* search current section first. */
  183.     
  184.     i = CurrentSection;
  185.     e_num = BEntrySearch(string, manual[i].entries, manual[i].nentries);
  186.     
  187.     /* search other sections. */
  188.     
  189.     if (e_num == NO_ENTRY) 
  190.     {
  191.     i = 0;            /* At the exit of the loop i needs to
  192.                    be the one we used. */
  193.     while ( TRUE ) 
  194.     {
  195.         if (i == CurrentSection)
  196.           if (++i >= sections) return(NULL);
  197.         e_num = BEntrySearch(string, manual[i].entries, manual[i].nentries);
  198.         if (e_num != NO_ENTRY) break;
  199.         if (++i >= sections) return(NULL);
  200.     }
  201.     }
  202.     
  203.     return(FindManualFile(i, e_num));
  204. }
  205.  
  206. /*    Function Name: BEntrySearch
  207.  *    Description: binary search through entries.
  208.  *    Arguments: string - the string to match.
  209.  *                 first - the first entry in the list.
  210.  *                 number - the number of entries.
  211.  *    Returns: a pointer to the entry found.
  212.  */
  213.  
  214. static int
  215. BEntrySearch(string, first, number)
  216. char * string;
  217. char ** first;
  218. int number;
  219. {
  220.   int check, cmp, len_cmp, global_number;
  221.   char *head, *tail;
  222.   
  223.   global_number = 0;
  224.   while (TRUE) {
  225.  
  226.     if (number == 0) {
  227.       return(NO_ENTRY);        /* didn't find it. */
  228.     }
  229.  
  230.     check = number/2;
  231.  
  232.     head = rindex(first[ global_number + check ], '/');
  233.     if (head == NULL) 
  234.       PrintError("index failure in BEntrySearch");
  235.     head++;
  236.  
  237.     tail = rindex(head, '.');
  238.     if (tail == NULL) 
  239.       PrintError("index failure in BEntrySearch");
  240.  
  241.     cmp = strncmp(string, head, (tail - head));
  242.     len_cmp = strlen(string) - (int) (tail - head);
  243.  
  244.     if ( cmp == 0 && len_cmp == 0) {
  245.       return(global_number + check);
  246.     }
  247.     else if ( cmp < 0 || ((cmp == 0) && (len_cmp < 0)) ) 
  248.       number = check;
  249.     else /* cmp > 0 || ((cmp == 0) && (len_cmp > 0)) */ {
  250.       global_number += (check + 1);
  251.       number -= ( check + 1 );
  252.     }
  253.   }
  254. }
  255.